package com.ocom.payconfig.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ocom.common.entity.card.EntityXfDeviceInfo;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.request.payconfig.*;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.StringUtils;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.dao.IDaoXfDeviceInfo;
import com.ocom.payconfig.service.XfDeviceInfoService;
import com.ocom.payconfig.vo.GetConsDeviceInfoVo;
import com.ocom.redis.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


@Service
public class XfDeviceInfoServiceImpl extends ServiceImpl<IDaoXfDeviceInfo, EntityXfDeviceInfo> implements XfDeviceInfoService {

	@Autowired
	private IDaoXfDeviceInfo xfDeviceInfo;


	@Resource
	private RedisUtil redisUtil;

	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public PageInfo<EntityXfDeviceInfo> getConsDeviceInfo(Long companyId,GetConsDeviceInfoRequest request){
		QueryWrapper<EntityXfDeviceInfo> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("com_id",request.getCom_id());
		if(!CommonUtil.isNull(request.getDevice_no())){
			queryWrapper.eq("device_no",request.getDevice_no());
		}
		if(!CommonUtil.isNull(request.getDevice_name())){
			queryWrapper.eq("device_name",request.getDevice_name());
		}
		if(request.getPoint_id()>0){
			queryWrapper.eq("point_id",request.getPoint_id());
		}
		if(request.getDevice_type()>0){
			queryWrapper.eq("device_type",request.getDevice_type());
		}
		if(request.getDevice_ver_type()>0){
			queryWrapper.eq("device_ver_type",request.getDevice_ver_type());
		}
		if(request.getStatus()>0){
			queryWrapper.eq("status",request.getStatus());
		}
		if(request.getDevice_mode()>0){
			queryWrapper.eq("device_mode",request.getDevice_mode());
		}
		if(!CommonUtil.isNull(request.getApp_ver())){
			queryWrapper.eq("app_ver",request.getApp_ver());
		}
		if(request.getPage()>0){
			Integer size=request.getSize()>0?request.getSize():50;
			PageHelper.startPage(request.getPage(),size);
			List<EntityXfDeviceInfo> pointInfoPageInfo=this.list(queryWrapper);
			PageInfo<EntityXfDeviceInfo> pageInfo=new PageInfo<>(pointInfoPageInfo);
			return pageInfo;
		}else{
			Integer size=request.getSize()>0?request.getSize():100;
			PageHelper.startPage(1,size);
			List<EntityXfDeviceInfo> pointInfoPageInfo=this.list(queryWrapper);
			PageInfo<EntityXfDeviceInfo> pageInfo=new PageInfo<>(pointInfoPageInfo);
			return pageInfo;
		}
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public EntityXfDeviceInfo addConsDeviceInfo(Long companyId,AddConsDeviceInfoRequest request){
		//TODO 机器号重复判断
		EntityXfDeviceInfo entityXfDeviceInfo=new EntityXfDeviceInfo();
		entityXfDeviceInfo.setComId(Long.valueOf(request.getComId()));
		entityXfDeviceInfo.setDeviceNo(request.getDeviceNo());
		entityXfDeviceInfo.setDeviceName(request.getDeviceName());
		entityXfDeviceInfo.setPointId(request.getPointId());
		entityXfDeviceInfo.setAiotNo(request.getAiotNo());
		entityXfDeviceInfo.setDeviceType(request.getDeviceType());
		entityXfDeviceInfo.setDeviceVerType(request.getDeviceVerType());
		entityXfDeviceInfo.setDeviceMode(request.getDeviceMode());
		entityXfDeviceInfo.setAppVer(request.getAppVer());
		entityXfDeviceInfo.setRemark(request.getRemark());
		entityXfDeviceInfo.setCreateUser(request.getCreateUser());
		entityXfDeviceInfo.setConsType(request.getConsType());
		boolean save = this.save(entityXfDeviceInfo);
		if(!save){
			return null;
		}
		return entityXfDeviceInfo;
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public EntityXfDeviceInfo updateConsDeviceInfo(Long companyId,UpdateConsDeviceInfoRequest request) throws ParseException {
		QueryWrapper<EntityXfDeviceInfo> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("com_id",request.getCom_id());
		queryWrapper.eq("device_no",request.getDevice_no());
		queryWrapper.last("limit 1");
		EntityXfDeviceInfo entityXfDeviceInfo=this.getOne(queryWrapper);
		// 判断null
		if(entityXfDeviceInfo==null){
			return null;
		}
		if(request.getPoint_id()!=null){
			entityXfDeviceInfo.setPointId(request.getPoint_id());
		}
		if(!CommonUtil.isNull(request.getDevice_name())){
			entityXfDeviceInfo.setDeviceName(request.getDevice_name());
		}
		if(request.getPoint_id()>0){
			entityXfDeviceInfo.setPointId(request.getPoint_id());
		}
		if(request.getDevice_type()>0){
			entityXfDeviceInfo.setDeviceType(request.getDevice_type());
		}
		if(request.getDevice_ver_type()>0){
			entityXfDeviceInfo.setDeviceVerType(request.getDevice_ver_type());
		}
		if(request.getDevice_mode()>0){
			entityXfDeviceInfo.setDeviceMode(request.getDevice_mode());
		}
		if(!CommonUtil.isNull(request.getEnd_time())){
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			entityXfDeviceInfo.setEndTime(format.parse(request.getEnd_time()));
		}
		if(!CommonUtil.isNull(request.getApp_ver())){
			entityXfDeviceInfo.setAppVer(request.getApp_ver());
		}
//		if(!CommonUtil.isNull(request.getApp_ver_tab())){
//			entityXfDeviceInfo.setAppVerTab(request.getApp_ver_tab());
//		}
//		if(!CommonUtil.isNull(request.getOs_ver_tab())){
//			entityXfDeviceInfo.setOsVerTab(request.getOs_ver_tab());
//		}
		if(request.getList_state()>0){
			entityXfDeviceInfo.setListState(request.getList_state());
		}
		if(!CommonUtil.isNull(request.getRemark())){
			entityXfDeviceInfo.setRemark(request.getRemark());
		}
		if(!CommonUtil.isNull(request.getUpdate_user())){
			entityXfDeviceInfo.setUpdateUser(request.getUpdate_user());
		}
		/**
		 * 人脸授权
		 */
		if(!CommonUtil.isNull(request.getFaceAuth())){
			entityXfDeviceInfo.setFaceAuth(request.getFaceAuth());
		}
		if(!CommonUtil.isNull(request.getFaceAuthTime())){
			try {
				entityXfDeviceInfo.setFaceAuthTime(DateUtils.strToDate(request.getFaceAuthTime()));
			}catch (Exception e){

			}
		}
		if(request.getFaceAuthType()!=null  && request.getFaceAuthType()>0){
			entityXfDeviceInfo.setFaceAuthType(request.getFaceAuthType());
		}


		entityXfDeviceInfo.setUpdateTime(new Date());
		entityXfDeviceInfo.setConsType(request.getConsType());

		entityXfDeviceInfo.setParaState(1);
		entityXfDeviceInfo.setParaJobid(String.valueOf(System.currentTimeMillis()));

		UpdateWrapper updateWrapper=new UpdateWrapper();
		updateWrapper.eq("com_id",entityXfDeviceInfo.getComId());
		updateWrapper.eq("device_no",entityXfDeviceInfo.getDeviceNo());
		boolean b=this.update(entityXfDeviceInfo,updateWrapper);
		if(!b){
			return null;
		}
		return entityXfDeviceInfo;
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public boolean deleteConsDeviceInfo(Long companyId,DeleteConsDeviceInfoRequest request){
		QueryWrapper<EntityXfDeviceInfo> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("com_id",request.getCom_id());
		queryWrapper.eq("device_no",request.getDevice_no());
		return  this.remove(queryWrapper);
	}

	// 2.14.获取消费设备信息(getConsDeviceInfo)
	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public List<EntityXfDeviceInfo> GetConsDeviceList(Long comId, GetConsDeviceInfoVo getConsDeviceInfoVo) {
		QueryWrapper<EntityXfDeviceInfo> query = Wrappers.query();
		query.eq("com_id",getConsDeviceInfoVo.getComId());
		if (StringUtils.isNotEmpty(getConsDeviceInfoVo.getDeviceNo())){
			query.eq("device_no",getConsDeviceInfoVo.getDeviceNo());
		}
		if (StringUtils.isNotEmpty(getConsDeviceInfoVo.getDeviceName())){
			query.like("device_name",getConsDeviceInfoVo.getDeviceName());
		}
		if (StringUtils.isNotNull(getConsDeviceInfoVo.getPointId())){
			query.eq("point_id",getConsDeviceInfoVo.getPointId());
		}
		if (StringUtils.isNotNull(getConsDeviceInfoVo.getStatus())){
			query.eq("status",getConsDeviceInfoVo.getStatus());
		}
		if (StringUtils.isNotNull(getConsDeviceInfoVo.getDeviceType())){
			query.eq("device_type",getConsDeviceInfoVo.getDeviceType());
		}
		if (StringUtils.isNotNull(getConsDeviceInfoVo.getDeviceVerType())){
			query.eq("device_ver_type",getConsDeviceInfoVo.getDeviceVerType());
		}
		if (StringUtils.isNotNull(getConsDeviceInfoVo.getDeviceMode())){
			query.eq("device_mode",getConsDeviceInfoVo.getDeviceMode());
		}
		if (StringUtils.isNotEmpty(getConsDeviceInfoVo.getAppVer())){
			query.eq("app_ver",getConsDeviceInfoVo.getAppVer());
		}
		PageHelper.startPage(getConsDeviceInfoVo.getPage(),getConsDeviceInfoVo.getSize());
		return xfDeviceInfo.selectList(query);
	}

	//将单位下的所有机器的白名单状态更新为1
	//行级锁
	@Transactional(isolation = Isolation.READ_COMMITTED)
	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
	@Override
	public void updateListState(Long comId) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.eq("com_id",comId);
		update.set("list_state",1);
		this.update(update);
	}

	//将单位下的所有机器的白名单状态更新为1
	@DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
	@Override
	public void updateListState(Long companyId,List<Long> comIds) {
		if (comIds ==null || comIds.size()==0){
			return;
		}
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.in("com_id",comIds);
		update.set("list_state",1);
		this.update(update);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public Boolean updatePara(Long comId) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.eq("com_id",comId);
		update.set("fkpara_state",1);
		Long jobid=System.currentTimeMillis();
		String strJobid= String.valueOf(jobid);
		update.set("fkpara_jobid",strJobid);
		update.set("para_jobid",strJobid);
		update.set("para_state",1);
		return this.update(update);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
	@Override
	public boolean UpdateList(Long companyId, String strMachNo) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.eq("com_id",companyId);
		if(strMachNo.contains(",")){
			update.inSql("device_no",strMachNo);
		}else{
			update.eq("device_no",strMachNo);
		}
		update.set("list_add",-1);
		update.set("list_add_tab",-1);
		update.set("list_delete",-1);
		update.set("list_delete_tab",-1);
		update.set("list_state",1);
		update.set("update_time",new Date());
		return this.update(update);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
	@Override
	public boolean UpdateResetMach(Long companyId, String strMachNo) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.eq("com_id",companyId);
		if(strMachNo.contains(",")){
			update.inSql("device_no",strMachNo);
		}else{
			update.eq("device_no",strMachNo);
		}
		String jobId= String.valueOf(System.currentTimeMillis());
		update.set("para_state",1);
		update.set("para_jobid",jobId);
		update.set("fkpara_state",1);
		update.set("fkpara_jobid",jobId);
		update.set("rsa_state",1);
		update.set("rsa_jobid",jobId);
		update.set("update_time",new Date());
		return this.update(update);
	}



	//获取消费设备信息
	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public EntityXfDeviceInfo GetDeviceInfo(Long comId, String machNo) {
		QueryWrapper<EntityXfDeviceInfo> query = Wrappers.query();
		query.eq("com_id",comId);
		query.eq("device_no",machNo);
		return xfDeviceInfo.selectOne(query);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public void updateAppVer(Long comId, String machNo, String versionCode) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.eq("com_id",comId);
		update.eq("device_no",machNo);
		update.set("app_ver",versionCode);
		this.update(update);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	public List<EntityXfDeviceInfo> getMachList(Long comId, Integer pointId) {
		QueryWrapper<EntityXfDeviceInfo> query = Wrappers.query();
		query.eq("com_id",comId);
		query.eq("point_id",pointId);
		return this.list(query);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public boolean updateMenuState(Long comId, String strPoints) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.set("menu_state",1);
		update.eq("com_id",comId);
		if (StringUtils.isNotEmpty(strPoints)){
			String[] arr=strPoints.split(",");
			update.in("point_id",arr);
		}
		return this.update(update);
	}


	@Override
	@DataSourceAspect(type= DataSourceEnum.PART_DB)
	public Boolean updateMenu(Long companyId, String machNo, Integer menuState, Integer menuAdd, Integer menuAddTab, Integer menuDelete, Integer menuMerchId) {
		UpdateWrapper<EntityXfDeviceInfo> updateWrapper=new UpdateWrapper<>();
		updateWrapper.eq("com_id",companyId);
		updateWrapper.eq("device_no",machNo);
		if(menuState!=null)  updateWrapper.set("menu_state",menuState);
		if(menuAdd!=null)  updateWrapper.set("menu_add",menuAdd);
		if(menuAddTab!=null)  updateWrapper.set("menu_add_tab",menuAddTab);
		if(menuDelete!=null)  updateWrapper.set("menu_delete",menuDelete);
		if(menuMerchId!=null)  updateWrapper.set("menu_merch_id",menuMerchId);
		updateWrapper.set("update_time",new Date());
		return this.update(updateWrapper);
	}

	@Override
	@DataSourceAspect(type= DataSourceEnum.PART_DB)
	public Boolean updateMenu(Long companyId, Integer pointId, Integer menuState, Integer menuAdd, Integer menuAddTab, Integer menuDelete, Integer menuMerchId) {
		UpdateWrapper<EntityXfDeviceInfo> updateWrapper=new UpdateWrapper<>();
		updateWrapper.eq("com_id",companyId);
		updateWrapper.eq("point_id",pointId);
		if(menuState!=null)  updateWrapper.set("menu_state",menuState);
		if(menuAdd!=null)  updateWrapper.set("menu_add",menuAdd);
		if(menuAddTab!=null)  updateWrapper.set("menu_add_tab",menuAddTab);
		if(menuDelete!=null)  updateWrapper.set("menu_delete",menuDelete);
		if(menuMerchId!=null)  updateWrapper.set("menu_merch_id",menuMerchId);
		updateWrapper.set("update_time",new Date());
		return this.update(updateWrapper);
	}


	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public boolean updateDishesAllDownload(Long comId, Integer merchId, String strPoints) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.set("menu_state",1);
		update.set("menu_add",-1);
		update.set("menu_add_tab",-1);
		update.set("menu_delete",-1);
		update.set("menu_merch_id",merchId);
		update.eq("com_id",comId);
		if (StringUtils.isNotEmpty(strPoints)){
			String[] arr=strPoints.split(",");
			update.in("point_id",arr);
		}
		return this.update(update);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	public List<EntityXfDeviceInfo> getMachList(Long comId, GetConsDeviceInfoByAgentRequest request) {
		QueryWrapper<EntityXfDeviceInfo> query = Wrappers.query();
		query.in("com_id",request.getComIds());
		if(!CommonUtil.isNull(request.getDeviceNo())){
			query.eq("device_no",request.getDeviceNo());
		}
		if(request.getDeviceType()!=null){
			query.eq("device_type",request.getDeviceType());
		}
		if(request.getDeviceVerType()!=null){
			query.eq("device_ver_type",request.getDeviceVerType());
		}
		return this.list(query);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public Boolean updateCodeUrl(Long companyId, String machNo, String codeUrl) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.set("code_pic_url",codeUrl);
		update.set("fkpara_state",1);
		update.set("fkpara_jobid",System.currentTimeMillis());
		update.eq("com_id",companyId);
		update.eq("device_no",machNo);
		return this.update(update);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public Boolean updateAccountCodePicUrl(Long companyId, String machNo, String codeUrl) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.set("account_code_pic_url",codeUrl);
		update.eq("com_id",companyId);
		update.eq("device_no",machNo);
		return this.update(update);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public Boolean removeConsDevicePayCode(Long companyId, String machNo) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.set("code_pic_url","");
		update.set("fkpara_state",1);
		update.set("fkpara_jobid",System.currentTimeMillis());
		update.eq("com_id",companyId);
		update.eq("device_no",machNo);
		return this.update(update);
	}

	@DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
	@Override
	public Boolean removeConsAccountPayCode(Long companyId, String machNo) {
		UpdateWrapper<EntityXfDeviceInfo> update = Wrappers.update();
		update.set("account_code_pic_url","");
		update.set("fkpara_state",1);
		update.set("fkpara_jobid",System.currentTimeMillis());
		update.eq("com_id",companyId);
		update.eq("device_no",machNo);
		return this.update(update);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public Boolean addConsDeviceInfo(Long companyId, EntityXfDeviceInfo entityXfDeviceInfo) {
		return this.save(entityXfDeviceInfo);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public EntityXfDeviceInfo getDeviceInfo2(Long companyId, String machNo,long inc) {
		QueryWrapper<EntityXfDeviceInfo> query = Wrappers.query();
		query.eq("com_id",companyId*10000+inc);
		query.eq("device_no",machNo);
		return this.getOne(query);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public void deleteSession(Long companyId) {
		QueryWrapper<EntityXfDeviceInfo> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("com_id",companyId);
		List<EntityXfDeviceInfo> list = this.list(queryWrapper);
		if(list!=null && list.size()>0){
			for (EntityXfDeviceInfo entityXfDeviceInfo:list){
				redisUtil.del("HttpXfDevice:"+entityXfDeviceInfo.getDeviceNo());
			}
		}

		QueryWrapper<EntityXfDeviceInfo> queryWrapper1=new QueryWrapper<>();
		queryWrapper1.eq("com_id",companyId*10000+2025l);
		List<EntityXfDeviceInfo> list1 = this.list(queryWrapper1);
		if(list1!=null && list1.size()>0){
			for (EntityXfDeviceInfo entityXfDeviceInfo:list1){
				redisUtil.del("HttpXfDevice:"+entityXfDeviceInfo.getDeviceNo());
			}
		}

		QueryWrapper<EntityXfDeviceInfo> queryWrapper2=new QueryWrapper<>();
		queryWrapper2.eq("com_id",companyId*10000+2026l);
		List<EntityXfDeviceInfo> list2 = this.list(queryWrapper2);
		if(list2!=null && list2.size()>0){
			for (EntityXfDeviceInfo entityXfDeviceInfo:list2){
				redisUtil.del("HttpXfDevice:"+entityXfDeviceInfo.getDeviceNo());
			}
		}
	}

}
